package io.renren.system.log.controller;

import io.renren.common.utils.Result;
import io.renren.system.log.vo.SysLogRunVo;
import io.renren.common.utils.BigNumber;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;


/**
 * 【日志管理-登录日志】
 */
@RestController
@RequestMapping("sys/log/run")
@Api(tags = "【日志管理-运行日志】")
@Slf4j
public class SysLogRunController {
    @Value("${LOG_HOME}")
    private String LOG_HOME;

    @GetMapping("page")
    @ApiOperation("按查询条件获取运行日志列表")
    @RequiresPermissions("sys:log:run:page")
    public Result<List<SysLogRunVo>> page(@ApiIgnore @RequestParam Map<String, Object> params) {
        String dirName = StringUtils.checkObj2Str(params.get("dirName"));
        String searchFileName = StringUtils.checkObj2Str(params.get("searchFileName"));

        String logPath = LOG_HOME;
        if (StringUtils.isNotEmpty(dirName)) {
            logPath += dirName;
        }
        List<SysLogRunVo> list = new ArrayList<>();
        File file = new File(logPath);
        File[] files = file.listFiles();
        SysLogRunVo vo = null;
        Integer dataType = null; // 类型(0-目录;1-文件)
        String fileName = "";
        String filePath = "";
        String fileSizeStr = "";
        Long fileSize;
        boolean result = false;

        Calendar cal = Calendar.getInstance();
        String lastModifiedTime = "";// 最后修改时间
        for (int i = 0; i < files.length; i++) {
            dataType = null;
            vo = new SysLogRunVo();
            fileName = files[i].getName();
            filePath = files[i].getAbsolutePath();
            filePath = filePath.replace("\\", "/").replace(LOG_HOME, "");
            if (StringUtils.isNotEmpty(searchFileName)) {
                if (fileName.contains(searchFileName)) {
                    result = true;
                } else {
                    result = false;
                }
            } else {
                result = true;
            }
            if (result) {
                dataType = files[i].isDirectory() ? 0 : 1;
                fileSize = files[i].isDirectory() ? FileUtils.sizeOfDirectory(new File(files[i].getAbsolutePath())) : files[i].length();
                fileSizeStr = this.changeFileSize2Str(fileSize);
                long time = files[i].lastModified();
                cal.setTimeInMillis(time);
                lastModifiedTime = DateUtils.formatLongDate(cal.getTime());

                vo.setXh((i + 1));// 序号
                vo.setDataType(dataType);// 类型(0-目录;1-文件)
                vo.setFileName(fileName);// 名称
                vo.setFilePath(filePath);// 地址
                vo.setFileSize(fileSizeStr);// 大小
                vo.setLastModifiedTime(lastModifiedTime);// 最后修改时间
                list.add(vo);
            }
        }

        // 对文件名倒叙排列
        Collections.sort(list, new Comparator<SysLogRunVo>() {
            @Override
            public int compare(SysLogRunVo m1, SysLogRunVo m2) {
                String fileName1 = m1.getFileName();
                String fileName2 = m2.getFileName();
                if (fileName1.compareTo(fileName2) < 0) {
                    return 1;
                } else if (fileName1.compareTo(fileName2) == 0) {
                    return 0;
                } else {
                    return -1;
                }
            }
        });
        return new Result<List<SysLogRunVo>>().ok(list);
    }

    /**
     * 计算文件大小
     *
     * @param fileSize
     * @return
     */
    private String changeFileSize2Str(long fileSize) {
        String strFileSize = "";
        long v1 = 1024;
        long v2 = 1024 * 1024;
        long v3 = 1024 * 1024 * 1024;
        if (fileSize >= 0 && fileSize < v1) {
            strFileSize = fileSize + "B";
        } else if (fileSize >= v1 && fileSize < v2) {
            strFileSize = BigNumber.div(String.valueOf(fileSize), String.valueOf(v1), 2).doubleValue() + "KB";
        } else if (fileSize >= v2 && fileSize < v3) {
            strFileSize = BigNumber.div(String.valueOf(fileSize), String.valueOf(v2), 2).doubleValue() + "MB";
        } else if (fileSize >= v3) {
            strFileSize = BigNumber.div(String.valueOf(fileSize), String.valueOf(v3), 2).doubleValue() + "GB";
        }
        return strFileSize;
    }


    /**
     * 下载项目运行日志
     *
     * @param response
     * @param filePath
     * @throws Exception
     */
    @RequestMapping(value = "downloadRunLogsFile")
    @ResponseBody
    @RequiresPermissions("sys:log:run:download")
    public void downloadProLogFile(HttpServletResponse response, String filePath) throws Exception {
        String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
        response.setContentType("application/octet-stream");
        String headFileName = new String(fileName.getBytes(), "ISO-8859-1");
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;fileName=" + headFileName);

        String fileRealPath = LOG_HOME + File.separator + filePath;
        InputStream inputStream = null;
        OutputStream os = null;
        try {
            File file = new File(fileRealPath);
            inputStream = new FileInputStream(file);
            os = response.getOutputStream();
            byte[] b = new byte[1024];
            int length;
            while ((length = inputStream.read(b)) > 0) {
                os.write(b, 0, length);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}